#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 30 avr. 2011

@author: alinehuf

The Class UiMainWindow is the "mother" of Graphic Interface,
it manages the implementation of all graphic elements.
It communicates with the controller that mediates
to communicate with the "business" part
'''

from PyQt4 import QtGui
from operator import itemgetter

from ui.UiElements import UiDamier, UiPersonnage 
from ui.UiInformations import UiMenu, UiZone, UiZoneEtiquette, UiAction 
from ui.UiDimension import UiDimension #
uiD = UiDimension()

class UiMainWindow(QtGui.QWidget):
    def __init__(self, controleur):
        '''
        Creation of the MainWindow
        '''
        super(UiMainWindow, self).__init__()
        self.controleur = controleur
        self.tailleCase = 0
        self.personnages = {}
        self.niveau = "niveau1" #default level if no choice is made in the menu
        
    def afficheMenu(self):
        '''
        Place the game window in the center of the screen and 
        show the StartUp Menu
        '''
        ecranW = QtGui.QDesktopWidget().screenGeometry().width()
        ecranH = QtGui.QDesktopWidget().screenGeometry().height()
        self.setGeometry((ecranW - uiD.fenetreW) / 2, (ecranH - uiD.fenetreH) / 2, \
                          uiD.fenetreW, uiD.fenetreH)
        self.setWindowTitle("Bienvenue dans TheShinProject !")
        self.uiMenu = UiMenu(self, "Bienvenue dans TheShinProject !", \
                             "Commencer la partie", "Quitter")

    def _jouer(self):
        '''
        This method is set to change, later the game will allow 
        the human player to compose his team and to place his 
        characters on the combat area
        '''
        self.uiMenu.deleteLater()
        self.setWindowTitle("TheShinProject - " + self.niveau)
        self.controleur.creerNouvellePartie(self.niveau)
        if self.niveau == "niveau1" : 
            self.controleur.creerPersonnage("Rankor", "Guerrier", "Nain")
            self.controleur.creerPersonnage("Asura", "Mage", "Mort-Vivant")
            self.controleur.creerPersonnage("Mantas",  "DeathKnight", "BloodElfe")
            self.controleur.creerPersonnage("Shu", "Archer", "Elfe")
            self.controleur.creerEquipe(["Rankor", "Asura"], ["Mantas","Shu"])
            self.controleur.positionnePersonnage("Rankor", "C2")
            self.personnages["Rankor"].regardeDroite()
            self.controleur.positionnePersonnage("Asura",    "B3")
            self.personnages["Shu"].regardeDroite()
            self.controleur.positionnePersonnage("Mantas", "J4")
            self.personnages["Mantas"].regardeGauche()
            self.controleur.positionnePersonnage("Shu",  "I5")
            self.personnages["Asura"].regardeDroite()
        if self.niveau == "niveau2" :
            self.controleur.creerPersonnage("Rankor", "Guerrier", "Nain")
            self.controleur.creerPersonnage("Shu", "Archer", "Elfe")
            self.controleur.creerPersonnage("Mantas",  "DeathKnight", "BloodElfe")
            self.controleur.creerPersonnage("Asura", "Mage", "Mort-Vivant")
            self.controleur.creerEquipe(["Rankor","Shu"], ["Mantas","Asura"])
            self.controleur.positionnePersonnage("Rankor", "K2")
            self.personnages["Rankor"].regardeGauche()
            self.controleur.positionnePersonnage("Shu",    "K4")
            self.personnages["Shu"].regardeGauche()
            self.controleur.positionnePersonnage("Mantas", "D4")
            self.personnages["Mantas"].regardeDroite()
            self.controleur.positionnePersonnage("Asura",  "B5")
            self.personnages["Asura"].regardeDroite()
        self.controleur.lancePartie()
    
    def afficheNouvellePartie(self, gameStatus):
        '''
        Initialization of the visual part of the game 
        ("damier", "personnages", displays "zones" around)
        '''
        size = self._getSizes(gameStatus)
        #--creation des widgets
        self.uiDamier = UiDamier(self, size["uiDamier"]["x"],
                                       size["uiDamier"]["y"],
                                       size["uiDamier"]["w"],
                                       size["uiDamier"]["h"],
                                       size["tailleCase"],
                                       size["width"], size["height"])
        self.uiDamier.setVisible(True)
        self.tailleCase = size["tailleCase"]
        self.uiTour = UiZone(self, u"Tour",
                                   size["uiTour"]["x"],
                                   size["uiTour"]["y"],
                                   size["uiTour"]["w"],
                                   size["uiTour"]["h"])
        self.uiTour.setVisible(True)
        self.uiActivite = UiZone(self, u"Activité",
                                       size["uiActivite"]["x"],
                                       size["uiActivite"]["y"],
                                       size["uiActivite"]["w"],
                                       size["uiActivite"]["h"])
        self.uiActivite.setVisible(True)
        self.uiPerso1 = UiZoneEtiquette(self, u"Personnage sélectionné",
                                          gameStatus.perso,
                                          size["uiPerso1"]["x"],
                                          size["uiPerso1"]["y"],
                                          size["uiPerso1"]["w"],
                                          size["uiPerso1"]["h"])
        self.uiPerso1.setVisible(True)
        self.uiPerso2 = UiZoneEtiquette(self, u"Personnage cible",
                                          gameStatus.perso,
                                          size["uiPerso2"]["x"],
                                          size["uiPerso2"]["y"],
                                          size["uiPerso2"]["w"],
                                          size["uiPerso2"]["h"])
        self.uiPerso2.setVisible(True)
        self.uiAction = UiAction(self, u"Action",
                                     size["uiAction"]["x"],
                                     size["uiAction"]["y"],
                                     size["uiAction"]["w"],
                                     size["uiAction"]["h"])
        self.uiAction.setVisible(True)
        self.uiTerrain = UiZoneEtiquette(self, u"Terrain",
                                      gameStatus.terrainLabel,
                                      size["uiTerrain"]["x"],
                                      size["uiTerrain"]["y"],
                                      size["uiTerrain"]["w"],
                                      size["uiTerrain"]["h"])
        self.uiTerrain.setVisible(True)
    
    def finDePartie(self, nomEquipeGagnante) :
        '''
        Destroy all the game Widgets and Show the startUp menu 
        with informations about the winner of the last game
        '''
        print nomEquipeGagnante
        if nomEquipeGagnante == "1" : 
            texte = u"Bravo Joueur n°1 ! Vous êtes vainqueur !!\n" + \
                    u"Voulez vous rejouer ?"
        elif nomEquipeGagnante == "2" : 
            texte = u"Bravo Joueur n°2 ! Vous êtes vainqueur !!\n" + \
                    u"Voulez vous rejouer ?"
        else :
            texte = u"Vous êtes à égalité,\n" + \
                    u"voulez vous tenter une autre partie ?"
        self.uiMenu = UiMenu(self, texte, "Rejouer", "Quitter")
        self.uiMenu.setVisible(True)
        self.uiDamier.deleteLater()
        self.uiTour.deleteLater()
        self.uiActivite.deleteLater()
        self.uiPerso1.deleteLater()
        self.uiPerso2.deleteLater()
        self.uiAction.deleteLater()
        self.uiTerrain.deleteLater()
    
    def updateUiZone(self, texte, nomZone):
        '''
        Change the text/data inside an information Box
        '''
        { 'uiTour': lambda texte: self.uiTour.changerTexte(texte),
          'uiActivite': lambda texte: self.uiActivite.changerTexte(texte),
          'uiPerso1': \
                    lambda texte: self.uiPerso1.changerTexte(texte),
          'uiPerso2': lambda texte: self.uiPerso2.changerTexte(texte),
          'uiAction': lambda texte: self.uiAction.changerTexte(texte),
          'uiTerrain': lambda texte: self.uiTerrain.changerTexte(texte),
        }[nomZone](texte)
    
    def updateUiDamier(self, damierStatus) :
        '''
        Allow to change the status of all the Cells of the battleground in once
        '''
        for case in damierStatus.cases:
            self.updateUiCase(case, damierStatus.cases[case])
        
    def updateUiCase(self, case, status) :
        '''
        Change the visible status of an UiCase to set it to selected, 
        possible Target, or possible choice
        '''
        style = ""
        if 'marque_selected' in status : style += uiD.styleCaseSelected
        else : style += uiD.styleCaseUnSelected
        
        if 'marque_choixPossible' in status : style += uiD.styleCaseReachable
        elif 'marque_ciblePossible' in status : style += uiD.styleCaseTarget
        else : style += uiD.styleCaseUnHighlight
        
        self.uiDamier.cases[case].setStyle(style)
    
    def creePersonnage(self, nom) :
        '''
        Create a UiPersonnage object and return it
        '''
        self.personnages[nom] = \
                UiPersonnage(self.uiDamier, nom, self.tailleCase)
        return self.personnages[nom]
    
    def updatePersonnage(self, nom, case) :
        '''
        Change the position of a character and position it in light of other
        '''
        offsetX = uiD.imagesPersonagesOffsetX * self.tailleCase
        offsetY = uiD.imagesPersonagesOffsetY * self.tailleCase
        caseX = self.uiDamier.cases[case].x * self.tailleCase + offsetX
        caseY = self.uiDamier.cases[case].y * self.tailleCase + offsetY
        self.personnages[nom].move(caseX, caseY)
        if self.personnages[nom].x - caseX > 0 :
            self.personnages[nom].regardeGauche()
        else : self.personnages[nom].regardeDroite()
        self.personnages[nom].x = caseX
        self.personnages[nom].y = caseY
        # to manage the overlapping characters
        ordre = [(p, self.personnages[p].y) for p in self.personnages]
        ordre.sort(key=itemgetter(1),reverse=True)
        for x in range(1, len(ordre)) :
            self.personnages[ordre[x][0]].stackUnder( \
                                        self.personnages[ordre[x - 1][0]] )
    
    @staticmethod
    def _getSizes(gameStatus):
        '''
        Calculates and return the dimensions of the interface areas, 
        grouped by to facilitate updating
        '''
        if gameStatus.damier.width : width = gameStatus.damier.width
        else : 
            print "gameStatus.damier.width is null !!!"
            exit(1)
        if gameStatus.damier.height : height = gameStatus.damier.height
        else : 
            print "gameStatus.damier.height is null !!!"
            exit(1)
        
        damierMaxWidth = uiD.fenetreW - uiD.uiTourWidth
        damierMaxHeight = uiD.fenetreH - uiD.UiZonesHeight
        tailleCaseWidth = damierMaxWidth / width
        tailleCaseHeight = damierMaxHeight / height
        if tailleCaseWidth > tailleCaseHeight:
            tailleCase = tailleCaseHeight
        else : tailleCase = tailleCaseWidth
        
        damierW = tailleCase * width
        damierH = tailleCase * height
        return { 'tailleCase' : tailleCase,
                 'width'      : width,
                 'height'     : height,
                 'uiDamier'   : { 'w' : (tailleCase * width),
                                  'h' : (tailleCase * height),
                                  'x' : (damierMaxWidth - damierW) /2,
                                  'y' : (damierMaxHeight - damierH) /2 },
                 'uiTour' : {     'w' : uiD.uiTourWidth,
                                  'h' : uiD.uiTourHeight,
                                  'x' : damierMaxWidth,
                                  'y' : 0 },
                 'uiActivite' : { 'w' : uiD.uiTourWidth,
                                  'h' : damierMaxHeight - uiD.uiTourHeight,
                                  'x' : damierMaxWidth,
                                  'y' : uiD.uiTourHeight },
                 'uiPerso1' : {   'w' : uiD.fenetreW / 4,
                                  'h' : uiD.UiZonesHeight,
                                  'x' : 0,
                                  'y' : damierMaxHeight },
                 'uiPerso2' : {   'w' : uiD.fenetreW / 4,
                                  'h' : uiD.UiZonesHeight,
                                  'x' : uiD.fenetreW / 4,
                                  'y' : damierMaxHeight },
                 'uiAction'   : { 'w' : uiD.fenetreW / 4,
                                  'h' : uiD.UiZonesHeight,
                                  'x' : uiD.fenetreW / 2,
                                  'y' : damierMaxHeight },
                 'uiTerrain'   : {'w' : uiD.fenetreW / 4,
                                  'h' : uiD.UiZonesHeight,
                                  'x' : uiD.fenetreW / 4 * 3,
                                  'y' : damierMaxHeight } }

